package net.sunofbeach.blog.controller.user;

import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import net.sunofbeach.blog.pojo.SobUser;
import net.sunofbeach.blog.response.ResponseResult;
import net.sunofbeach.blog.services.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserApi {

    @Autowired
    private IUserService userService;


    /**
     * 初始化管理员账号
     */
    @PostMapping("/admin_account")
    public ResponseResult initManagerAccount(@RequestBody SobUser sobUser, HttpServletRequest request) {
        log.info("user name == >" + sobUser.getUserName());
        log.info("password == >" + sobUser.getPassword());
        log.info("email == >" + sobUser.getEmail());
        return userService.initManagerAccount(sobUser, request);
    }

    /**
     * 注册
     */

    @PostMapping("/join_in")
    public ResponseResult register(@RequestBody SobUser sobUser,
                                   @RequestParam("email_code") String emailCode,
                                   @RequestParam("captcha_code") String captchaCode) {

        return userService.register(sobUser, emailCode, captchaCode);

    }

    /**
     * 登录 sign-up
     * 1.用户账户-可以昵称，可以邮箱------->做了唯一处理
     * 2.密码
     * 3.图灵验证码
     * 4.图灵验证的key
     *
     * @param captcha 图灵验证码
     * @param sobUser 用户bean类，封装着账户密码
     */

    @PostMapping("/login/{captcha}/")
    public ResponseResult login(@PathVariable("captcha") String captcha,
                                @RequestBody SobUser sobUser,
                                @RequestParam(value = "from", required = false) String from) {
        return userService.doLogin(captcha, sobUser, from);
    }


    /**
     * 获取图灵验证码
     */
    @GetMapping("/captcha")
    public void getCaptcha(HttpServletResponse response) {

        try {
            userService.createCaptcha(response);
        } catch (Exception e) {
            log.error(e.toString());
        }


    }

    /**
     * 发送邮件
     * <p>
     * 使用场景：注册，找回密码，修改邮箱
     * 注册：如果已经注册了，就提示，改邮箱已注册
     * 找回密码：如果没注册过，就提示改邮箱没有注册
     * 修改邮箱：如果已经注册了，提示该邮箱已经注册
     * localhost:2020/user/verify_code?type=forget&email=1292196066@qq.com
     */
    @GetMapping("/verify_code")
    public ResponseResult sendVerifyCode(HttpServletRequest request,
                                         @RequestParam("type") String type,
                                         @RequestParam("email") String emailAddress,
                                         @RequestParam("captchaCode") String captchaCode) {
        log.info("email ==>" + emailAddress);
        return userService.sendEmail(request, type, emailAddress, captchaCode);
    }

    /**
     * 修改密码
     * 修改密码，找回密码
     * 普通做法：通过旧密码对比来更新密码
     * <p>
     * 找回密码：，也可以修改密码
     * 发送验证码到邮箱/手机---> 判断验证码是否正确
     * 对应邮箱/手机号码所注册的账号属于你
     * <p>
     * 步骤：
     * 1。用户填写邮箱
     * 2.用户获取验证码type=forget
     * 3.填写验证码
     * 4.填写新的密码
     * 5.提交数据
     * <p>
     * 数据包括：
     * 1.邮箱和新密码
     * 2.验证码
     * <p>
     * 如果验证码正确-->所拥有像注册的帐号就是你的，可以修改密码
     * localhost:2020/password/629018
     */
    @PutMapping("/password/{verifyCode}")
    public ResponseResult updatePassword(@PathVariable String verifyCode,
                                         @RequestBody SobUser sobUser) {
        return userService.updateUserPassword(verifyCode, sobUser);
    }

    /**
     * 获取作者信息user-info
     */
    @GetMapping("/user_info/{userId}")
    public ResponseResult getUserInfo(@PathVariable("userId") String userId) {
        return userService.getUserInfo(userId);
    }

    /**
     * 修改用户信息
     * <p>
     * 允许用户修改的信息
     * 1.头像
     * 2.用户名
     * 3.密码（单独修改）
     * 4.签名
     * 5.email（唯一的，单独修改）
     */
    @PutMapping("/user_info/{userId}")
    public ResponseResult updateUserInfo(@PathVariable String userId,
                                         @RequestBody SobUser sobUser) {
        return userService.updateUserInfo(userId, sobUser);
    }


    /**
     * 获取用户列表
     * 权限：管理员权限
     *
     * @param page
     * @param size
     * @return
     */
    @PreAuthorize("@permission.admin()")
    @GetMapping("/list")
    public ResponseResult listUsers(@RequestParam("page") int page,
                                    @RequestParam("size") int size,
                                    @RequestParam(value = "userName", required = false) String userName,
                                    @RequestParam(value = "email", required = false) String email) {
        return userService.listUsers(page, size, userName, email);
    }


    /**
     * 需要管理员权限
     *
     * @param userId
     * @return
     */
    @PreAuthorize("@permission.admin()")
    @DeleteMapping("/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") String userId) {
        //判断当前用户的用户是谁
        //根据用户角色判断是否可以删除
        return userService.deleteUserById(userId);
    }

    /**
     * 检查该email是否已经注册
     *
     * @param email 邮箱地址
     * @return SSUccESS 表示已经注册了，反之，就是没注册
     */

    @ApiResponses({
            @ApiResponse(code = 20000, message = "表示当前邮箱已经注册"),
            @ApiResponse(code = 40000, message = "表示当前邮箱未注册"),
    })
    @GetMapping("/email")
    public ResponseResult checkEmail(@RequestParam("email") String email) {

        return userService.checkEmail(email);
    }

    /**
     * 检查该用户名是否已经注册
     *
     * @param userName 用户名
     * @return SSUccESS 表示已经注册了，反之，就是没注册
     */

    @ApiResponses({
            @ApiResponse(code = 20000, message = "表示当前用户名已经注册"),
            @ApiResponse(code = 40000, message = "表示当前用户名未注册"),
    })
    @GetMapping("/user_name")
    public ResponseResult checkUserName(@RequestParam("userName") String userName) {

        return userService.checkUserName(userName);
    }

    /**
     * 1.必须已经登录
     * 2.新的邮箱没有注册过
     * <p>
     * 用户步骤
     * 1.已经登陆
     * 2.输入新的邮箱
     * 3.获取验证码type=update
     * 4.输入验证码
     * 5.提交数据
     * <p>
     * <p>
     * 需要提交的数据
     * 1.新的邮箱地址
     * 2.验证码
     * 3.其他信息可以从token里获取
     *
     * @return
     */
    @PutMapping("/email")
    public ResponseResult updateEmail(@RequestParam("email") String email,
                                      @RequestParam("verify_code") String verifyCode
    ) {

        return userService.updateEmail(email, verifyCode);
    }


    /**
     * 退出登录
     * <p>
     * 拿到token_key
     * 删除redis里对应的token
     * 删除mysql里的refreshToken
     * 删除cookie里的token_key
     *
     * @return
     */
    @GetMapping("/logout")
    public ResponseResult logout() {

        return userService.doLogout();
    }

    /**
     * 获取二维码
     * 二维码的图片路径
     * 二维码的内容字符串
     *
     * @return
     */

    @GetMapping("/pc-login-qr-code")
    public ResponseResult getPcLoginQrCode() {

        return userService.getPcLoginQrCodeInfo();

    }

    /**
     * 检查二维码的登陆状态
     *
     * @return
     */
    @GetMapping("/qr-code-state/{loginId}")
    public ResponseResult CheckQrCodeLoginState(@PathVariable("loginId") String loginId) {

        return userService.CheckQrCodeLoginState(loginId);

    }


    @PutMapping("/qr-code-state/{loginId}")
    public ResponseResult updateQrCodeLoginState(@PathVariable("loginId") String loginId) {

        return userService.updateQrCodeLoginState(loginId);

    }

    @GetMapping("/check-token")
    public ResponseResult parseToken() {
        return userService.parseToken();
    }


    @PreAuthorize("@permission.admin()")
    @PutMapping("/reset-password/{userId}")
    public ResponseResult resetPassword(@PathVariable("userId") String userId,
                                        @RequestParam("password") String password) {
        return userService.resetPassword(userId, password);
    }


    @GetMapping("/register_count")
    public ResponseResult getRegisterCount() {
        return userService.getRegisterCount();
    }


    @GetMapping("/check_email_code")
    public ResponseResult checkEmailCode(@RequestParam("email") String email,
                                         @RequestParam("emailCode") String emailCode,
                                         @RequestParam("captchaCode") String captchaCode) {
        return userService.checkEmailCode(email, emailCode, captchaCode);

    }

}
